package com.pickgliss.light2d.display
{
	import com.pickgliss.ds.IRecycle;
	import com.pickgliss.light2d.texture.ITexture;
	import com.pickgliss.light2d.texture.ImageTexture;
	import com.pickgliss.light2d.texture.TextureFactory;
	import com.pickgliss.loaders.LoaderManager;
	import com.pickgliss.ui.core.Disposeable;
	
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.Program3D;
	import flash.display3D.VertexBuffer3D;
	import flash.geom.Matrix;
	import flash.geom.Matrix3D;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	import flash.utils.getTimer;
	
	import mx.messaging.AbstractConsumer;

	public class LightImage implements Disposeable, IRecycle
	{
		public function LightImage()
		{
			_textureType=TextureFactory.IMAGE_TEXTURE;
		}

		public var registerPoint:Point=new Point(0, 0);
		protected var _indexBuffer:IndexBuffer3D;
		protected var _modelMatrix:Matrix3D=new Matrix3D();
		protected var _program3D:Program3D;
		protected var _projectionMatrix:Matrix3D=new Matrix3D();
		protected var _scale:Number=1;

		protected var _textureId:String="";
		protected var _textureType:int;
		protected var _vertextBuffer:VertexBuffer3D;
		protected var _uvBuffer:VertexBuffer3D;
		protected var _x:int;
		protected var _y:int;

		private var _texture:ITexture;

		public function dispose():void
		{
		}
		
		public function render():void
		{
			if (createTexture())
			{
				var last:int = getTimer();
				prepare();
				var c1:int = getTimer();
//				trace("prepare : ",String(c1-last));
				last = c1;
				updateModelMatrix();
				c1 = getTimer();
//				trace("updateModelMatrix : ",String(c1-last));
				last = c1;
				updateProjectionMatrix();
				c1 = getTimer();
//				trace("updateProjectionMatrix : ",String(c1-last));
				last = c1;
				draw();
				c1 = getTimer();
//				trace("draw : ",String(c1-last));
				last = c1;
			}
		}

		public function reset():void
		{

		}

		public function get scale():Number
		{
			return _scale;
		}

		public function set scale(value:Number):void
		{
			_scale=value;
		}

		public function get texture():ITexture
		{
			return _texture;
		}

		public function set texture(value:ITexture):void
		{
			_texture=value;
		}

		public function get textureId():String
		{
			return _textureId;
		}

		public function set textureId(value:String):void
		{
			_textureId=value;
		}

		public function get x():int
		{
			return _x;
		}

		public function set x(value:int):void
		{
			_x=value;
		}

		public function get y():int
		{
			return _y;
		}

		public function set y(value:int):void
		{
			_y=value;
		}

		protected function createTexture():Boolean
		{
			if (_texture != null && _texture.textureId == _textureId)
				return true;
			if (_textureId == "")
			{
				_texture=null;
				return false;
			}
			_texture=TextureFactory.Instance.createTexture(_textureId, _textureType);
			return false;
		}

		protected function draw():void
		{
			var context:Context3D=LightStage.context3D;
			context.setVertexBufferAt(0, _vertextBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
			context.setVertexBufferAt(1, _uvBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
			context.setTextureAt(0, _texture.texture);
			context.setProgram(_program3D);
			context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, _projectionMatrix, true);
			context.drawTriangles(_indexBuffer);
		}

		protected function prepare():void
		{
			_texture.step();
			_vertextBuffer=_texture.getVetextBuffer();
			_uvBuffer = _texture.getUVBuffer();
			_indexBuffer=_texture.getIndexBuffer();
			_program3D=_texture.getProgram();
		}

		protected function updateModelMatrix():void
		{
			_modelMatrix.identity();
			_modelMatrix.appendTranslation(_x, _y, 0);
			_modelMatrix.appendScale(_scale,_scale,1);
		}

		protected function updateProjectionMatrix():void
		{
			_projectionMatrix.identity();
			_projectionMatrix.append(_texture.getDefaultMatrix());
			_projectionMatrix.append(_modelMatrix);
			_projectionMatrix.append(LightStage.worldMatrix);
		}
	}
}
